package org.liukai.tutorial.service;

import com.google.common.collect.Sets;
import org.apache.log4j.Logger;
import org.liukai.tutorial.domain.Authority;
import org.liukai.tutorial.domain.Role;
import org.liukai.tutorial.domain.User;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Set;

@Transactional(readOnly = true)
public class UserDetailsServiceImpl implements UserDetailsService {

    protected static Logger logger = Logger.getLogger("service");

    @Resource(name = "accountService")
    private IAccountService service;

    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException, DataAccessException {
        User user = service.getUserInfo(username);
        if (user == null) {
            throw new UsernameNotFoundException("用户{ " + username + " }不存在!");
        }
        Set<GrantedAuthority> grantedAuths = obtainGrantedAuthorities(user);

        // -- mini-web示例中无以下属性, 暂时全部设为true. --//
        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;

        UserDetails userdetails = new org.springframework.security.core.userdetails.User(
                user.getLoginName(), user.getPassword(), enabled,
                accountNonExpired, credentialsNonExpired, accountNonLocked,
                grantedAuths);
        return userdetails;
    }

    /**
     * 获得当前User的权限('ROLE_' 开头的)
     */
    private Set<GrantedAuthority> obtainGrantedAuthorities(User user) {

        Set<GrantedAuthority> authSet = Sets.newHashSet();

        for (Role role : user.getRoleList()) {
            for (Authority authority : role.getAuthorityList()) {
                authSet.add(new GrantedAuthorityImpl(authority
                        .getPrefixedName()));
            }
        }

        return authSet;

    }

}
